#include "uart.h"
#include <string.h>


typedef struct
{
    uint16_t    usReceiveLen;           //接收到的数据长度
    uint8_t     *pReceiveBuff;          //接受数据缓冲区
    uint16_t    usMaxReceiveLen;        //缓冲区最大长度
    pUartReceiveCallback    pRecCallback;   //接收回调函数
    uint32_t    ulByteInterval;         //字节间超时
    uint32_t    ulRecentTimestamp;      //最近一次接收到字节的系统时基
}UART_PARAM;


static UART_PARAM s_UartParam[UART_NUM];

static pUartGetTimeStamp g_pfGetTimeStamp = NULL;

/**
* @函数名:      UartInit
* @功能描述:    初始化串口
* @输入参数:    uart:串口结构体
* @输出参数:    无
* @返回值:      无
*/
void UartInit(UART_ID id,uint32_t baud,uint8_t* receiveBuff,uint16_t maxLen,uint32_t interval,pUartReceiveCallback f)
{
    GPIO_TypeDef *GPIO;
    uint32_t TxPin;
    uint32_t RxPin;
    USART_TypeDef *UartDef;
    NVIC_InitTypeDef NVIC_InitStructure;
    GPIO_InitTypeDef Port;
    IRQn_Type   UartIRQ;
    USART_InitTypeDef   USART_InitStructure;
    switch(id)
    {
        case UART_1:
        {
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);
            GPIO = GPIOA;
            TxPin = GPIO_Pin_9;
            RxPin = GPIO_Pin_10;
            UartDef = USART1;
            UartIRQ = USART1_IRQn;
            break;
        }
        case UART_2:
        {
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
            GPIO = GPIOA;
            TxPin = GPIO_Pin_2;
            RxPin = GPIO_Pin_3;
            UartDef = USART2;
            UartIRQ = USART2_IRQn;
            break;
        }
        case UART_3:
        {
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
            GPIO = GPIOB;
            TxPin = GPIO_Pin_10;
            RxPin = GPIO_Pin_11;
            UartDef = USART3;
            UartIRQ = USART3_IRQn;
            break;
        }
        case UART_4:
        {
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4,ENABLE);
            GPIO = GPIOC;
            TxPin = GPIO_Pin_10;
            RxPin = GPIO_Pin_11;
            UartDef = UART4;
            UartIRQ = UART4_IRQn;
            break;
        }
        default:return;
    }
    
    Port.GPIO_Pin = TxPin;
    Port.GPIO_Speed = GPIO_Speed_50MHz;
    Port.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIO,&Port);

    Port.GPIO_Pin = RxPin;
    Port.GPIO_Speed = GPIO_Speed_50MHz;
    Port.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIO,&Port);
     
    
    USART_InitStructure.USART_BaudRate = baud;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;

    memset(&s_UartParam[id],0,sizeof(s_UartParam[0]));

    s_UartParam[id].pReceiveBuff = receiveBuff;
    s_UartParam[id].usReceiveLen = 0;
    s_UartParam[id].ulByteInterval = interval;
    s_UartParam[id].usMaxReceiveLen = maxLen;
    s_UartParam[id].pRecCallback = f;
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitStructure.NVIC_IRQChannel = UartIRQ;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = id;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    USART_Init(UartDef, &USART_InitStructure);
    USART_ITConfig(UartDef, USART_IT_RXNE, ENABLE);
    USART_Cmd(UartDef, ENABLE);
}

/**
* @函数名:      UartDeinit
* @功能描述:    反初始化串口
* @输入参数:    
* @输出参数:    无
* @返回值:      无
*/
void UartDeinit(UART_ID id)
{
    USART_TypeDef *UartDef;
    switch(id)
    {
        case UART_1:
            UartDef = USART1;	
			break;
		
		case UART_2:
            UartDef = USART2;
			break;
		
		case UART_3:
            UartDef = USART3;	
			break;
		
		case UART_4:
            UartDef = UART4;	
			break;
        default:return;
    }
    USART_Cmd(UartDef, DISABLE);
    USART_ITConfig(UartDef, USART_IT_RXNE, DISABLE);
    USART_DeInit(UartDef);
}

/**
* @函数名:      SetUartTimeStamp
* @功能描述:    设置1msTICK函数
* @输入参数:    pUartGetTimeStamp
* @输出参数:    无
* @返回值:      无
*/
void SetUartTimeStamp(pUartGetTimeStamp fun)
{
    g_pfGetTimeStamp = fun;
}

/**
* @函数名:      UartRead
* @功能描述:    读取串口数据
* @输入参数:    needCopy:是否需要拷贝,buf：拷贝的数据，len最大读取字节数
* @输出参数:    无
* @返回值:      实际读到的字节数
*/
uint16_t UartRead(UART_ID id,bool needCopy,uint8_t* buff,uint16_t len)
{
    if(id >= UART_NUM && g_pfGetTimeStamp == 0)
        return 0;
    if(s_UartParam[id].usReceiveLen && g_pfGetTimeStamp()-s_UartParam[id].ulRecentTimestamp >= s_UartParam[id].ulByteInterval)
    {
        uint16_t retLen = s_UartParam[id].usReceiveLen;
		if(retLen >= s_UartParam[id].usMaxReceiveLen)
			retLen = s_UartParam[id].usMaxReceiveLen - 1;
		s_UartParam[id].pReceiveBuff[retLen] = 0;
		if(len < retLen)
			retLen = len;
        if(needCopy)
        {
            memcpy(buff,&s_UartParam[id].pReceiveBuff[0],retLen);
        }
        s_UartParam[id].usReceiveLen = 0;
        return retLen;
    }
    return 0;
}

/**
* @函数名:      UartSend
* @功能描述:    写串口数据
* @输入参数:    buf：写入的数据，len写入的字节数
* @输出参数:    无
* @返回值:      是否成功发送
*/
bool UartSend(UART_ID id,const uint8_t* buff,uint16_t len)
{
    USART_TypeDef *uartDef;
    switch(id)
    {
        case UART_1:
        {
            uartDef = USART1;
            break;
        }
        case UART_2:{
            uartDef = USART2;
            break;
        }
        case UART_3:{
            uartDef = USART3;
            break;
        }
        case UART_4:{
            uartDef = UART4;
            break;
        }
        default:return false;
    }
    uint16_t i = 0;
    for(;i<len;i++)
    {
        USART_SendData(uartDef,*(buff+i));
        while(USART_GetFlagStatus(uartDef,USART_FLAG_TC)==RESET);
    }
    return true;
    
}


//异常字节读取
volatile static uint8_t ErrorByte = 0;

void USART1_IRQHandler(void)
{
    uint8_t tmp08; 
    //发生接收中断
    if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
    {
        tmp08 = USART_ReceiveData(USART1);
        if(s_UartParam[UART_1].usReceiveLen < s_UartParam[UART_1].usMaxReceiveLen)
        {
            s_UartParam[UART_1].pReceiveBuff[s_UartParam[UART_1].usReceiveLen] = tmp08;
            s_UartParam[UART_1].usReceiveLen++;
        }
        s_UartParam[UART_1].ulRecentTimestamp = g_pfGetTimeStamp();
        USART_ClearITPendingBit(USART1, USART_IT_RXNE); 
    }
    //发生完成中断
    else if(USART_GetITStatus(USART1, USART_IT_TC) == SET)
    {
      //清除中断标志
      USART_ClearITPendingBit(USART1, USART_IT_TC);
    }
    else if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) == SET)
    {
        ErrorByte = USART_ReceiveData(USART1);
    }
    
}

void USART2_IRQHandler(void)
{
    uint8_t tmp08;    
    //发生接收中断
    if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
    {
        tmp08 = USART_ReceiveData(USART2);
        if(s_UartParam[UART_2].usReceiveLen < s_UartParam[UART_2].usMaxReceiveLen)
        {
            s_UartParam[UART_2].pReceiveBuff[s_UartParam[UART_2].usReceiveLen] = tmp08;
            s_UartParam[UART_2].usReceiveLen++;
        }
        s_UartParam[UART_2].ulRecentTimestamp = g_pfGetTimeStamp();
        USART_ClearITPendingBit(USART2, USART_IT_RXNE); 
    }
    //发生完成中断
    else if(USART_GetITStatus(USART2, USART_IT_TC) == SET)
    {
      //清除中断标志
      USART_ClearITPendingBit(USART2, USART_IT_TC);
    }
    else if(USART2->SR >>3&0x01)
    {
        ErrorByte = USART_ReceiveData(USART2);
    }
}

void USART3_IRQHandler(void)
{
    uint8_t tmp08; 
    //发生接收中断
    if(USART_GetITStatus(USART3, USART_IT_RXNE) == SET)
    {
        tmp08 = USART_ReceiveData(USART3);
        if(s_UartParam[UART_3].usReceiveLen < s_UartParam[UART_3].usMaxReceiveLen)
        {
            s_UartParam[UART_3].pReceiveBuff[s_UartParam[UART_3].usReceiveLen] = tmp08;
            s_UartParam[UART_3].usReceiveLen++;
        }
        s_UartParam[UART_3].ulRecentTimestamp = g_pfGetTimeStamp();
        USART_ClearITPendingBit(USART3, USART_IT_RXNE); 
    }
    //发生完成中断
    else if(USART_GetITStatus(USART3, USART_IT_TC) == SET)
    {
      //清除中断标志
      USART_ClearITPendingBit(USART3, USART_IT_TC);
    }
    else if(USART3->SR >>3&0x01)
    {
        ErrorByte = USART_ReceiveData(USART3);
    }
}

void UART4_IRQHandler(void)
{
    uint8_t tmp08; 
    //发生接收中断
    if(USART_GetITStatus(UART4, USART_IT_RXNE) == SET)
    {
        tmp08 = USART_ReceiveData(UART4);
        if(s_UartParam[UART_4].usReceiveLen < s_UartParam[UART_4].usMaxReceiveLen)
        {
            s_UartParam[UART_4].pReceiveBuff[s_UartParam[UART_4].usReceiveLen] = tmp08;
            s_UartParam[UART_4].usReceiveLen++;
        }
        s_UartParam[UART_4].ulRecentTimestamp = g_pfGetTimeStamp();
        USART_ClearITPendingBit(UART4, USART_IT_RXNE); 
    }
    //发生完成中断
    else if(USART_GetITStatus(UART4, USART_IT_TC) == SET)
    {
      //清除中断标志
      USART_ClearITPendingBit(UART4, USART_IT_TC);
    }
    else if(UART4->SR >>3&0x01)
    {
        ErrorByte = USART_ReceiveData(UART4);
    }
}

